CM3D2 Converter.menu_OBJECT_PT_cm3d2_menu
1import bpy 2import math 3import mathutils 4import struct 5from . import common 6from . import compat 7from . import menu_file 8 9''' CM3D2 Menu / Object Panel Classes ''' 10 11@compat.BlRegister() 12class CM3D2MENU_UL_command_list(bpy.types.UIList): 13 bl_idname = 'CM3D2MENU_UL_command_list' 14 bl_options = {'DEFAULT_CLOSED'} 15 bl_region_type = 'WINDOW' 16 bl_space_type = 'PROPERTIES' 17 # The draw_item function is called for each item of the collection that is visible in the list. 18 # data is the RNA object containing the collection, 19 # item is the current drawn item of the collection, 20 # icon is the "computed" icon for the item (as an integer, because some objects like materials or textures 21 # have custom icons ID, which are not available as enum items). 22 # active_data is the RNA object containing the active property for the collection (i.e. integer pointing to the 23 # active item of the collection). 24 # active_propname is the name of the active property (use 'getattr(active_data, active_propname)'). 25 # index is index of the current item in the collection. 26 # flt_flag is the result of the filtering process for this item. 27 # Note: as index and flt_flag are optional arguments, you do not have to use/declare them here if you don't 28 # need them. 29 def draw_item(self, context, layout, data, item, icon, active_data, active_propname): 30 command_prop = item.dereference(data) 31 # draw_item must handle the three layout types... Usually 'DEFAULT' and 'COMPACT' can share the same code. 32 if self.layout_type in {'DEFAULT', 'COMPACT'}: 33 # You should always start your row layout by a label (icon + text), or a non-embossed text field, 34 # this will also make the row easily selectable in the list! The later also enables ctrl-click rename. 35 # We use icon_value of label, as our given icon is an integer value, not an enum ID. 36 # Note "data" names should never be translated! 37 if command_prop: 38 command_enum_info = menu_file.get_command_enum_info(command_prop.command) 39 icon = 'NONE' 40 if command_enum_info: 41 icon = compat.icon(command_enum_info[3]) 42 layout.label(text=command_prop.name, icon=icon) 43 else: 44 layout.label(text="", translate=False, icon_value=icon) 45 # 'GRID' layout type should be as compact as possible (typically a single icon!). 46 elif self.layout_type in {'GRID'}: 47 layout.alignment = 'CENTER' 48 layout.label(text="", icon_value=icon) 49 50 51@compat.BlRegister() 52class OBJECT_PT_cm3d2_menu(bpy.types.Panel): 53 bl_space_type = 'PROPERTIES' 54 bl_region_type = 'WINDOW' 55 bl_context = 'object' 56 bl_label = 'CM3D2 Menu' 57 bl_idname = 'OBJECT_PT_cm3d2_menu' 58 59 @classmethod 60 def poll(cls, context): 61 ob = context.object 62 if ob: 63 return True 64 return False 65 66 def draw(self, context): 67 ob = context.object 68 69 row = self.layout.row(align=True) 70 row.operator('cm3d2menu.import', text="Import CM3D2 Menu File", icon=compat.icon('IMPORT')) 71 row.operator('cm3d2menu.export', text="Export CM3D2 Menu File", icon=compat.icon('EXPORT')) 72 73 cm3d2_menu = ob.cm3d2_menu 74 active_command = cm3d2_menu.get_active_command() 75 76 col = self.layout.column() 77 col.prop(cm3d2_menu, 'version' , translate=False) 78 col.prop(cm3d2_menu, 'path' , translate=False) 79 col.prop(cm3d2_menu, 'name' , translate=False) 80 col.prop(cm3d2_menu, 'category' , translate=False) 81 col.prop(cm3d2_menu, 'description', translate=False, expand=True) 82 83 row = self.layout.row() 84 row.template_list('CM3D2MENU_UL_command_list', '', 85 cm3d2_menu, 'commands' , 86 cm3d2_menu, 'active_index', 87 ) 88 sub_col = row.column(align=True) 89 sub_col.operator('cm3d2menu.command_add' , icon='ADD' , text="") 90 sub_col.operator('cm3d2menu.command_remove', icon='REMOVE', text="") 91 #sub_col.separator() 92 #sub_col.menu("OBJECT_MT_cm3d2_menu_context_menu", icon='DOWNARROW_HLT', text="") 93 if active_command: 94 sub_col.separator() 95 sub_col.operator("cm3d2menu.command_move", icon='TRIA_UP' , text="").direction = 'UP' 96 sub_col.operator("cm3d2menu.command_move", icon='TRIA_DOWN', text="").direction = 'DOWN' 97 98 if active_command: 99 box = self.layout.box() 100 if not compat.IS_LEGACY: 101 box.use_property_split = True 102 cm3d2_menu.get_active_command().draw(context, box) 103 104 105 106 107''' CM3D2 Menu Operators ''' 108 109@compat.BlRegister() 110class CM3D2MENU_OT_import(bpy.types.Operator): 111 bl_idname = 'cm3d2menu.import' 112 bl_label = "Import CM3D2 Menu File" 113 bl_description = "Open a .menu file" 114 bl_options = {'REGISTER', 'UNDO'} 115 116 filepath = bpy.props.StringProperty(subtype='FILE_PATH') 117 filename_ext = '.menu' 118 filter_glob = bpy.props.StringProperty(default='*.menu', options={'HIDDEN'}) 119 120 @classmethod 121 def poll(cls, context): 122 ob = context.object 123 if ob and ob in context.editable_objects: 124 return True 125 return False 126 127 def invoke(self, context, event): # type: (bpy.types.Context, Any) -> set 128 prefs = common.preferences() 129 if prefs.menu_import_path: 130 self.filepath = prefs.menu_import_path 131 else: 132 self.filepath = prefs.menu_default_path 133 134 context.window_manager.fileselect_add(self) 135 return {'RUNNING_MODAL'} 136 137 def execute(self, context): 138 ob = context.object 139 try: 140 file = open(self.filepath, 'rb') 141 ob.cm3d2_menu.clear() 142 ob.cm3d2_menu.unpack_from_file(file) 143 except IOError as e: 144 self.report(type={'ERROR'}, message=e.args[0]) 145 return {'CANCELLED'} 146 return {'FINISHED'} 147 148 149@compat.BlRegister() 150class CM3D2MENU_OT_export(bpy.types.Operator): 151 bl_idname = 'cm3d2menu.export' 152 bl_label = "Export CM3D2 Menu File" 153 bl_description = "Writes the active CM3D2Menu to a .menu file" 154 bl_options = {'REGISTER', 'UNDO'} 155 156 filepath = bpy.props.StringProperty(subtype='FILE_PATH') 157 filename_ext = '.menu' 158 filter_glob = bpy.props.StringProperty(default='*.menu', options={'HIDDEN'}) 159 160 is_backup = bpy.props.BoolProperty(name="Backup", default=True, description="Will backup overwritten files.") 161 162 @classmethod 163 def poll(cls, context): 164 ob = context.object 165 if ob and len(ob.cm3d2_menu.commands): 166 return True 167 return False 168 169 def invoke(self, context, event): # type: (bpy.types.Context, Any) -> set 170 prefs = common.preferences() 171 if prefs.menu_import_path: 172 self.filepath = prefs.menu_import_path 173 else: 174 self.filepath = prefs.menu_default_path 175 176 context.window_manager.fileselect_add(self) 177 return {'RUNNING_MODAL'} 178 179 def draw(self, context): 180 box = self.layout.box() 181 box.prop(self, 'is_backup', icon='FILE_BACKUP') 182 183 def execute(self, context): 184 ob = context.object 185 try: 186 file = common.open_temporary(self.filepath, 'wb', is_backup=self.is_backup) 187 ob.cm3d2_menu.pack_into_file(file) 188 except IOError as e: 189 self.report(type={'ERROR'}, message=e.args[0]) 190 return {'CANCELLED'} 191 self.report(type={'INFO'}, message="Successfully exported to .menu file") 192 return {'FINISHED'} 193 194 195@compat.BlRegister() 196class CM3D2MENU_OT_command_add(bpy.types.Operator): 197 bl_idname = 'cm3d2menu.command_add' 198 bl_label = "Add Command" 199 bl_description = "Adds a new CM3D2MenuCommand to the active CM3D2Menu" 200 bl_options = {'REGISTER', 'UNDO'} 201 202 command_type_enums = menu_file.COMMAND_ENUMS.copy() 203 command_type_enums.append( ('NONE', 'Custom', 'Some other manually entered miscillaneous command', 'GREASEPENCIL', -1) ) 204 type = bpy.props.EnumProperty(items=command_type_enums, name="Type", default='NONE') 205 206 string = bpy.props.StringProperty(name="String", default="newcommand") 207 208 @classmethod 209 def poll(cls, context): 210 ob = context.object 211 if ob: 212 return True 213 return False 214 215 def invoke(self, context, event): 216 return context.window_manager.invoke_props_dialog(self) 217 218 def draw(self, context): 219 self.layout.prop(self, 'type') 220 if self.type == 'NONE': 221 self.layout.prop(self, 'string') 222 223 def execute(self, context): 224 ob = context.object 225 cm3d2_menu = ob.cm3d2_menu 226 if self.type != 'NONE': 227 self.string = self.type 228 229 cm3d2_menu.new_command(self.string) 230 cm3d2_menu.active_index = len(cm3d2_menu.commands) - 1 231 232 return {'FINISHED'} 233 234 235@compat.BlRegister() 236class CM3D2MENU_OT_command_remove(bpy.types.Operator): 237 bl_idname = 'cm3d2menu.command_remove' 238 bl_label = "Remove Command" 239 bl_description = "Removes the active CM3D2MenuCommand from the active CM3D2Menu" 240 bl_options = {'REGISTER', 'UNDO'} 241 242 @classmethod 243 def poll(cls, context): 244 ob = context.object 245 if ob and len(ob.cm3d2_menu.commands) - ob.cm3d2_menu.active_index > 0: 246 return True 247 return False 248 249 def execute(self, context): 250 ob = context.object 251 cm3d2_menu = ob.cm3d2_menu 252 cm3d2_menu.remove_command(cm3d2_menu.active_index) 253 if cm3d2_menu.active_index >= len(cm3d2_menu.commands): 254 cm3d2_menu.active_index = len(cm3d2_menu.commands) - 1 255 256 return {'FINISHED'} 257 258 259@compat.BlRegister() 260class CM3D2MENU_OT_command_move(bpy.types.Operator): 261 bl_idname = 'cm3d2menu.command_move' 262 bl_label = "Move Command" 263 bl_description = "Moves the active CM3D2MenuCommand up/down in the list" 264 bl_options = {'REGISTER', 'UNDO'} 265 266 items = [ 267 ('UP' , "Up" , "Move the active CM3D2MenuCommand up in the list" ), 268 ('DOWN', "Down", "Move the active CM3D2MenuCommand down in the list"), 269 ] 270 direction = bpy.props.EnumProperty(items=items, name="Direction") 271 272 @classmethod 273 def poll(cls, context): 274 ob = context.object 275 if ob and len(ob.cm3d2_menu.commands) - ob.cm3d2_menu.active_index > 0: 276 return True 277 return False 278 279 def execute(self, context): 280 ob = context.object 281 cm3d2_menu = ob.cm3d2_menu 282 283 new_index = cm3d2_menu.active_index - 1 if self.direction == 'UP' else cm3d2_menu.active_index + 1 284 if new_index >= len(cm3d2_menu.commands): 285 new_index = len(cm3d2_menu.commands) - 1 286 elif new_index < 0: 287 new_index = 0 288 289 cm3d2_menu.move_command(cm3d2_menu.active_index, new_index) 290 cm3d2_menu.active_index = new_index 291 292 return {'FINISHED'} 293 294 295 296 297''' CM3D2 Menu Command Operators ''' 298 299# For menu_file.CM3D2MENU_PG_AttachPointCommand 300 301@compat.BlRegister() 302class CM3D2MENU_OT_align_selected_to_attach_point(bpy.types.Operator): 303 bl_idname = 'cm3d2menu.align_selected_to_attach_point' 304 bl_label = "Align Selected to Attach Point" 305 bl_description = "Align other selected objects to the active object's active CM3D2 attach point" 306 bl_options = {'REGISTER', 'UNDO'} 307 308 scale = bpy.props.FloatProperty(name="Scale", default=5, min=0.1, max=100, soft_min=0.1, soft_max=100, step=100, precision=1, description="The amount by which the mesh is scaled when imported. Recommended that you use the same when at the time of export.") 309 310 @classmethod 311 def poll(cls, context): 312 ob = context.object 313 arm_ob = None 314 if ob.type == 'ARMATURE': 315 arm_ob = ob 316 else: 317 arm_ob = ob.find_armature() 318 if (not arm_ob) and (ob.parent and ob.parent.type == 'ARMATURE'): 319 arm_ob = ob.parent 320 321 if arm_ob and arm_ob.type == 'ARMATURE': 322 active_command = ob.cm3d2_menu.get_active_command() 323 if type(active_command) != menu_file.CM3D2MENU_PG_AttachPointCommand: 324 return False 325 326 selection = None 327 try: 328 selection = context.selected_editable_objects 329 except: 330 return False 331 332 if not selection or len(selection) < 1: 333 return False 334 335 for selected in selection: 336 if selected != arm_ob and selected != ob: 337 return True 338 339 return False 340 341 def invoke(self, context, event): 342 self.scale = common.preferences().scale 343 return context.window_manager.invoke_props_dialog(self) 344 345 def draw(self, context): 346 self.layout.prop(self, 'scale') 347 348 def execute(self, context): 349 ob = context.object 350 if ob.type == 'ARMATURE': 351 arm_ob = ob 352 else: 353 arm_ob = ob.find_armature() 354 if (not arm_ob) and (ob.parent and ob.parent.type == 'ARMATURE'): 355 arm_ob = ob.parent 356 selection = context.selected_editable_objects 357 358 attach_point = ob.cm3d2_menu.get_active_command() 359 attach_mat = attach_point.rotation.to_matrix().to_4x4() 360 attach_mat.translation = attach_point.location.copy() * self.scale 361 362 attach_basis = compat.convert_cm_to_bl_space(attach_mat) 363 attach_basis = compat.convert_cm_to_bl_bone_rotation(attach_basis) 364 365 for selected in selection: 366 if selected == arm_ob or selected == ob: 367 continue 368 const = selected.constraints.get("CM3D2 Attachment") 369 if not const: 370 const = selected.constraints.new("CHILD_OF") 371 const.name = "CM3D2 Attachment" 372 const.target = arm_ob 373 selected.matrix_basis = attach_basis 374 375 return {'FINISHED'} 376 377 378@compat.BlRegister() 379class CM3D2MENU_OT_align_attach_point_to_selected(bpy.types.Operator): 380 bl_idname = 'cm3d2menu.align_attach_point_to_selected' 381 bl_label = "Align Attach Point to Selected" 382 bl_description = "Align the active CM3D2Menu's active attach point to the first other selected object" 383 bl_options = {'REGISTER', 'UNDO'} 384 385 scale = bpy.props.FloatProperty(name="Scale", default=5, min=0.1, max=100, soft_min=0.1, soft_max=100, step=100, precision=1, description="The amount by which the mesh is scaled when imported. Recommended that you use the same when at the time of export.") 386 387 @classmethod 388 def poll(cls, context): 389 ob = context.object 390 arm_ob = None 391 if ob.type == 'ARMATURE': 392 arm_ob = ob 393 else: 394 arm_ob = ob.find_armature() 395 if (not arm_ob) and (ob.parent and ob.parent.type == 'ARMATURE'): 396 arm_ob = ob.parent 397 398 if arm_ob and arm_ob.type == 'ARMATURE': 399 active_command = ob.cm3d2_menu.get_active_command() 400 if type(active_command) != menu_file.CM3D2MENU_PG_AttachPointCommand: 401 return False 402 403 selection = None 404 try: 405 selection = context.selected_objects 406 except: 407 return False 408 409 if not selection or len(selection) < 1: 410 return False 411 412 for selected in selection: 413 if selected != arm_ob and selected != ob: 414 return True 415 416 return False 417 418 def invoke(self, context, event): 419 self.scale = common.preferences().scale 420 return context.window_manager.invoke_props_dialog(self) 421 422 def draw(self, context): 423 self.layout.prop(self, 'scale') 424 425 def execute(self, context): 426 ob = context.object 427 if ob.type == 'ARMATURE': 428 arm_ob = ob 429 else: 430 arm_ob = ob.find_armature() 431 if (not arm_ob) and (ob.parent and ob.parent.type == 'ARMATURE'): 432 arm_ob = ob.parent 433 selection = context.selected_objects 434 435 attach_point = ob.cm3d2_menu.get_active_command() 436 437 438 for selected in selection: 439 if selected == arm_ob or selected == ob: 440 continue 441 mat = compat.mul(arm_ob.matrix_world.inverted(), selected.matrix_world) 442 mat = compat.convert_bl_to_cm_space(mat) 443 mat = compat.convert_bl_to_cm_bone_rotation(mat) 444 445 attach_point.location = mat.translation * (1/self.scale) 446 attach_point.rotation = mat.to_euler() 447 448 return {'FINISHED'} 449 450 451 452# For menu_file.CM3D2MENU_PG_MiscCommand 453 454@compat.BlRegister() 455class CM3D2MENU_OT_param_add(bpy.types.Operator): 456 bl_idname = 'cm3d2menu.param_add' 457 bl_label = "Add Parameter" 458 bl_description = "Adds a new CM3D2MenuParam to the active CM3D2MenuCommand" 459 bl_options = {'REGISTER', 'UNDO'} 460 461 @classmethod 462 def poll(cls, context): 463 ob = context.object 464 if ob and ob.cm3d2_menu: 465 misc_command = ob.cm3d2_menu.get_active_command() 466 if type(misc_command) == menu_file.CM3D2MENU_PG_MiscCommand: 467 return True 468 return False 469 470 def execute(self, context): 471 ob = context.object 472 cm3d2_menu = ob.cm3d2_menu 473 misc_command = ob.cm3d2_menu.get_active_command() 474 misc_command.new_param() 475 misc_command.active_index = len(misc_command.params) - 1 476 477 return {'FINISHED'} 478 479 480@compat.BlRegister() 481class CM3D2MENU_OT_param_remove(bpy.types.Operator): 482 bl_idname = 'cm3d2menu.param_remove' 483 bl_label = "Remove Parameter" 484 bl_description = "Removes the active CM3D2MenuParam from the active CM3D2MenuCommand" 485 bl_options = {'REGISTER', 'UNDO'} 486 487 @classmethod 488 def poll(cls, context): 489 ob = context.object 490 if not ob or not ob.cm3d2_menu: 491 return False 492 493 misc_command = ob.cm3d2_menu.get_active_command() 494 if type(misc_command) != menu_file.CM3D2MENU_PG_MiscCommand: 495 return False 496 497 if len(misc_command.params) - misc_command.active_index <= 0: 498 return False 499 500 return True 501 502 def execute(self, context): 503 ob = context.object 504 cm3d2_menu = ob.cm3d2_menu 505 misc_command = ob.cm3d2_menu.get_active_command() 506 misc_command.remove_param(misc_command.active_index) 507 if misc_command.active_index >= len(misc_command.params): 508 misc_command.active_index = len(misc_command.params) - 1 509 510 return {'FINISHED'} 511 512 513@compat.BlRegister() 514class CM3D2MENU_OT_param_move(bpy.types.Operator): 515 bl_idname = 'cm3d2menu.param_move' 516 bl_label = "Move Parameter" 517 bl_description = "Moves the active CM3D2MenuParameter up/down in the list" 518 bl_options = {'REGISTER', 'UNDO'} 519 520 items = [ 521 ('UP' , "Up" , "Move the active CM3D2MenuCommand up in the list" ), 522 ('DOWN', "Down", "Move the active CM3D2MenuCommand down in the list"), 523 ] 524 direction = bpy.props.EnumProperty(items=items, name="Direction") 525 526 @classmethod 527 def poll(cls, context): 528 ob = context.object 529 if not ob or not ob.cm3d2_menu: 530 return False 531 532 misc_command = ob.cm3d2_menu.get_active_command() 533 if type(misc_command) != menu_file.CM3D2MENU_PG_MiscCommand: 534 return False 535 536 if len(misc_command.params) - misc_command.active_index <= 0: 537 return False 538 539 return True 540 541 def execute(self, context): 542 ob = context.object 543 cm3d2_menu = ob.cm3d2_menu 544 misc_command = ob.cm3d2_menu.get_active_command() 545 546 new_index = misc_command.active_index - 1 if self.direction == 'UP' else misc_command.active_index + 1 547 if new_index >= len(misc_command.params): 548 new_index = len(misc_command.params) - 1 549 elif new_index < 0: 550 new_index = 0 551 552 misc_command.move_param(misc_command.active_index, new_index) 553 misc_command.active_index = new_index 554 555 return {'FINISHED'}
@compat.BlRegister()
class
CM3D2MENU_UL_command_list12@compat.BlRegister() 13class CM3D2MENU_UL_command_list(bpy.types.UIList): 14 bl_idname = 'CM3D2MENU_UL_command_list' 15 bl_options = {'DEFAULT_CLOSED'} 16 bl_region_type = 'WINDOW' 17 bl_space_type = 'PROPERTIES' 18 # The draw_item function is called for each item of the collection that is visible in the list. 19 # data is the RNA object containing the collection, 20 # item is the current drawn item of the collection, 21 # icon is the "computed" icon for the item (as an integer, because some objects like materials or textures 22 # have custom icons ID, which are not available as enum items). 23 # active_data is the RNA object containing the active property for the collection (i.e. integer pointing to the 24 # active item of the collection). 25 # active_propname is the name of the active property (use 'getattr(active_data, active_propname)'). 26 # index is index of the current item in the collection. 27 # flt_flag is the result of the filtering process for this item. 28 # Note: as index and flt_flag are optional arguments, you do not have to use/declare them here if you don't 29 # need them. 30 def draw_item(self, context, layout, data, item, icon, active_data, active_propname): 31 command_prop = item.dereference(data) 32 # draw_item must handle the three layout types... Usually 'DEFAULT' and 'COMPACT' can share the same code. 33 if self.layout_type in {'DEFAULT', 'COMPACT'}: 34 # You should always start your row layout by a label (icon + text), or a non-embossed text field, 35 # this will also make the row easily selectable in the list! The later also enables ctrl-click rename. 36 # We use icon_value of label, as our given icon is an integer value, not an enum ID. 37 # Note "data" names should never be translated! 38 if command_prop: 39 command_enum_info = menu_file.get_command_enum_info(command_prop.command) 40 icon = 'NONE' 41 if command_enum_info: 42 icon = compat.icon(command_enum_info[3]) 43 layout.label(text=command_prop.name, icon=icon) 44 else: 45 layout.label(text="", translate=False, icon_value=icon) 46 # 'GRID' layout type should be as compact as possible (typically a single icon!). 47 elif self.layout_type in {'GRID'}: 48 layout.alignment = 'CENTER' 49 layout.label(text="", icon_value=icon)
def
draw_item( self, context, layout, data, item, icon, active_data, active_propname):
30 def draw_item(self, context, layout, data, item, icon, active_data, active_propname): 31 command_prop = item.dereference(data) 32 # draw_item must handle the three layout types... Usually 'DEFAULT' and 'COMPACT' can share the same code. 33 if self.layout_type in {'DEFAULT', 'COMPACT'}: 34 # You should always start your row layout by a label (icon + text), or a non-embossed text field, 35 # this will also make the row easily selectable in the list! The later also enables ctrl-click rename. 36 # We use icon_value of label, as our given icon is an integer value, not an enum ID. 37 # Note "data" names should never be translated! 38 if command_prop: 39 command_enum_info = menu_file.get_command_enum_info(command_prop.command) 40 icon = 'NONE' 41 if command_enum_info: 42 icon = compat.icon(command_enum_info[3]) 43 layout.label(text=command_prop.name, icon=icon) 44 else: 45 layout.label(text="", translate=False, icon_value=icon) 46 # 'GRID' layout type should be as compact as possible (typically a single icon!). 47 elif self.layout_type in {'GRID'}: 48 layout.alignment = 'CENTER' 49 layout.label(text="", icon_value=icon)
Inherited Members
- bpy_types._GenericUI
- is_extended
- append
- prepend
- remove
- builtins.bpy_struct
- keys
- values
- items
- get
- pop
- as_pointer
- keyframe_insert
- keyframe_delete
- driver_add
- driver_remove
- is_property_set
- property_unset
- is_property_readonly
- is_property_overridable_library
- property_overridable_library_set
- path_resolve
- path_from_id
- type_recast
- bl_rna_get_subclass_py
- bl_rna_get_subclass
- id_properties_ensure
- id_properties_clear
- id_properties_ui
- id_data
@compat.BlRegister()
class
CM3D2MENU_OT_import110@compat.BlRegister() 111class CM3D2MENU_OT_import(bpy.types.Operator): 112 bl_idname = 'cm3d2menu.import' 113 bl_label = "Import CM3D2 Menu File" 114 bl_description = "Open a .menu file" 115 bl_options = {'REGISTER', 'UNDO'} 116 117 filepath = bpy.props.StringProperty(subtype='FILE_PATH') 118 filename_ext = '.menu' 119 filter_glob = bpy.props.StringProperty(default='*.menu', options={'HIDDEN'}) 120 121 @classmethod 122 def poll(cls, context): 123 ob = context.object 124 if ob and ob in context.editable_objects: 125 return True 126 return False 127 128 def invoke(self, context, event): # type: (bpy.types.Context, Any) -> set 129 prefs = common.preferences() 130 if prefs.menu_import_path: 131 self.filepath = prefs.menu_import_path 132 else: 133 self.filepath = prefs.menu_default_path 134 135 context.window_manager.fileselect_add(self) 136 return {'RUNNING_MODAL'} 137 138 def execute(self, context): 139 ob = context.object 140 try: 141 file = open(self.filepath, 'rb') 142 ob.cm3d2_menu.clear() 143 ob.cm3d2_menu.unpack_from_file(file) 144 except IOError as e: 145 self.report(type={'ERROR'}, message=e.args[0]) 146 return {'CANCELLED'} 147 return {'FINISHED'}
filepath: <_PropertyDeferred, <built-in function StringProperty>, {'subtype': 'FILE_PATH', 'attr': 'filepath'}> =
<_PropertyDeferred, <built-in function StringProperty>, {'subtype': 'FILE_PATH', 'attr': 'filepath'}>
filter_glob: <_PropertyDeferred, <built-in function StringProperty>, {'default': '*.menu', 'options': {'HIDDEN'}, 'attr': 'filter_glob'}> =
<_PropertyDeferred, <built-in function StringProperty>, {'default': '*.menu', 'options': {'HIDDEN'}, 'attr': 'filter_glob'}>
def
invoke(self, context, event):
128 def invoke(self, context, event): # type: (bpy.types.Context, Any) -> set 129 prefs = common.preferences() 130 if prefs.menu_import_path: 131 self.filepath = prefs.menu_import_path 132 else: 133 self.filepath = prefs.menu_default_path 134 135 context.window_manager.fileselect_add(self) 136 return {'RUNNING_MODAL'}
Inherited Members
- bpy_types.Operator
- as_keywords
- poll_message_set
- builtins.bpy_struct
- keys
- values
- items
- get
- pop
- as_pointer
- keyframe_insert
- keyframe_delete
- driver_add
- driver_remove
- is_property_set
- property_unset
- is_property_readonly
- is_property_overridable_library
- property_overridable_library_set
- path_resolve
- path_from_id
- type_recast
- bl_rna_get_subclass_py
- bl_rna_get_subclass
- id_properties_ensure
- id_properties_clear
- id_properties_ui
- id_data
@compat.BlRegister()
class
CM3D2MENU_OT_export150@compat.BlRegister() 151class CM3D2MENU_OT_export(bpy.types.Operator): 152 bl_idname = 'cm3d2menu.export' 153 bl_label = "Export CM3D2 Menu File" 154 bl_description = "Writes the active CM3D2Menu to a .menu file" 155 bl_options = {'REGISTER', 'UNDO'} 156 157 filepath = bpy.props.StringProperty(subtype='FILE_PATH') 158 filename_ext = '.menu' 159 filter_glob = bpy.props.StringProperty(default='*.menu', options={'HIDDEN'}) 160 161 is_backup = bpy.props.BoolProperty(name="Backup", default=True, description="Will backup overwritten files.") 162 163 @classmethod 164 def poll(cls, context): 165 ob = context.object 166 if ob and len(ob.cm3d2_menu.commands): 167 return True 168 return False 169 170 def invoke(self, context, event): # type: (bpy.types.Context, Any) -> set 171 prefs = common.preferences() 172 if prefs.menu_import_path: 173 self.filepath = prefs.menu_import_path 174 else: 175 self.filepath = prefs.menu_default_path 176 177 context.window_manager.fileselect_add(self) 178 return {'RUNNING_MODAL'} 179 180 def draw(self, context): 181 box = self.layout.box() 182 box.prop(self, 'is_backup', icon='FILE_BACKUP') 183 184 def execute(self, context): 185 ob = context.object 186 try: 187 file = common.open_temporary(self.filepath, 'wb', is_backup=self.is_backup) 188 ob.cm3d2_menu.pack_into_file(file) 189 except IOError as e: 190 self.report(type={'ERROR'}, message=e.args[0]) 191 return {'CANCELLED'} 192 self.report(type={'INFO'}, message="Successfully exported to .menu file") 193 return {'FINISHED'}
filepath: <_PropertyDeferred, <built-in function StringProperty>, {'subtype': 'FILE_PATH', 'attr': 'filepath'}> =
<_PropertyDeferred, <built-in function StringProperty>, {'subtype': 'FILE_PATH', 'attr': 'filepath'}>
filter_glob: <_PropertyDeferred, <built-in function StringProperty>, {'default': '*.menu', 'options': {'HIDDEN'}, 'attr': 'filter_glob'}> =
<_PropertyDeferred, <built-in function StringProperty>, {'default': '*.menu', 'options': {'HIDDEN'}, 'attr': 'filter_glob'}>
is_backup: <_PropertyDeferred, <built-in function BoolProperty>, {'name': 'Backup', 'default': True, 'description': 'Will backup overwritten files.', 'attr': 'is_backup'}> =
<_PropertyDeferred, <built-in function BoolProperty>, {'name': 'Backup', 'default': True, 'description': 'Will backup overwritten files.', 'attr': 'is_backup'}>
def
invoke(self, context, event):
170 def invoke(self, context, event): # type: (bpy.types.Context, Any) -> set 171 prefs = common.preferences() 172 if prefs.menu_import_path: 173 self.filepath = prefs.menu_import_path 174 else: 175 self.filepath = prefs.menu_default_path 176 177 context.window_manager.fileselect_add(self) 178 return {'RUNNING_MODAL'}
def
execute(self, context):
184 def execute(self, context): 185 ob = context.object 186 try: 187 file = common.open_temporary(self.filepath, 'wb', is_backup=self.is_backup) 188 ob.cm3d2_menu.pack_into_file(file) 189 except IOError as e: 190 self.report(type={'ERROR'}, message=e.args[0]) 191 return {'CANCELLED'} 192 self.report(type={'INFO'}, message="Successfully exported to .menu file") 193 return {'FINISHED'}
Inherited Members
- bpy_types.Operator
- as_keywords
- poll_message_set
- builtins.bpy_struct
- keys
- values
- items
- get
- pop
- as_pointer
- keyframe_insert
- keyframe_delete
- driver_add
- driver_remove
- is_property_set
- property_unset
- is_property_readonly
- is_property_overridable_library
- property_overridable_library_set
- path_resolve
- path_from_id
- type_recast
- bl_rna_get_subclass_py
- bl_rna_get_subclass
- id_properties_ensure
- id_properties_clear
- id_properties_ui
- id_data
@compat.BlRegister()
class
CM3D2MENU_OT_command_add196@compat.BlRegister() 197class CM3D2MENU_OT_command_add(bpy.types.Operator): 198 bl_idname = 'cm3d2menu.command_add' 199 bl_label = "Add Command" 200 bl_description = "Adds a new CM3D2MenuCommand to the active CM3D2Menu" 201 bl_options = {'REGISTER', 'UNDO'} 202 203 command_type_enums = menu_file.COMMAND_ENUMS.copy() 204 command_type_enums.append( ('NONE', 'Custom', 'Some other manually entered miscillaneous command', 'GREASEPENCIL', -1) ) 205 type = bpy.props.EnumProperty(items=command_type_enums, name="Type", default='NONE') 206 207 string = bpy.props.StringProperty(name="String", default="newcommand") 208 209 @classmethod 210 def poll(cls, context): 211 ob = context.object 212 if ob: 213 return True 214 return False 215 216 def invoke(self, context, event): 217 return context.window_manager.invoke_props_dialog(self) 218 219 def draw(self, context): 220 self.layout.prop(self, 'type') 221 if self.type == 'NONE': 222 self.layout.prop(self, 'string') 223 224 def execute(self, context): 225 ob = context.object 226 cm3d2_menu = ob.cm3d2_menu 227 if self.type != 'NONE': 228 self.string = self.type 229 230 cm3d2_menu.new_command(self.string) 231 cm3d2_menu.active_index = len(cm3d2_menu.commands) - 1 232 233 return {'FINISHED'}
command_type_enums =
[('', 'Menu Meta', ''), ('end', 'End', 'description', 'X', 0), ('name', 'Menu Name', 'description', 'FILE_TEXT', 3), ('saveitem', 'Menu Category', 'description', 'FILE_TEXT', 4), ('setumei', 'Menu Description', 'description', 'FILE_TEXT', 5), ('priority', 'Priority', 'description', 'SORT_DESC', 6), ('メニューフォルダ', 'Folder', 'description', 'FILE_FOLDER', 7), ('icon', 'Icon', 'description', 'FILE_IMAGE', 10), ('icons', 'Icon (Small)', 'description', 'FILE_IMAGE', 11), ('iconl', 'Icon (Large)', 'Unused', 'BLANK1', 12), ('', 'Item Meta', ''), ('ver', 'Item Version', 'description', 'FILE_TEXT', 20), ('category', 'Item Category', 'description', 'SORTALPHA', 21), ('catno', 'Item Category Number', 'description', 'LINENUMBERS_ON', 22), ('アイテム', 'Item', 'description', 'FILE_3D', 30), ('アイテム条件', 'Item Conditions', 'description', 'SCRIPTPLUGINS', 31), ('if', 'Item If', 'description', 'FILE_SCRIPT', 32), ('アイテムパラメータ', 'Item Parameters', 'description', 'SCRIPTPLUGINS', 33), ('半脱ぎ', 'Item Half Off', 'description', 'LIBRARY_DATA_INDIRECT', 34), ('リソース参照', 'Item Resource Reference', 'description', 'LIBRARY_DATA_INDIRECT', 35), ('', 'Item Control', ''), ('set', 'Set', 'Unused', 'BLANK1', 40), ('setname', 'Set Name', 'Unused', 'BLANK1', 41), ('setslotitem', 'Set Slot Item', 'description', 'FILE_TICK', 42), ('additem', 'Add Item', 'description', 'ADD', 43), ('unsetitem', 'Unset Item', 'description', 'REMOVE', 44), ('nofloory', 'Disable Item Floor', 'description', 'CON_FLOOR', 45), ('maskitem', 'Mask Item', 'description', 'MOD_MASK', 46), ('delitem', 'Delete Item', 'description', 'TRASH', 47), ('node消去', 'Node Hide', 'description', 'HIDE_ON', 50), ('node表示', 'Node Display', 'description', 'HIDE_OFF', 51), ('パーツnode消去', 'Parts-Node Hide', 'description', 'VIS_SEL_01', 52), ('パーツnode表示', 'Parts-Node Display', 'description', 'VIS_SEL_11', 53), ('', 'Material Control', ''), ('color', 'Color', 'description', 'COLOR', 60), ('mancolor', 'Man Color', 'description', 'GHOST_ENABLED', 61), ('color_set', 'Color-Set', 'description', 'GROUP_VCOL', 62), ('tex', 'Texture', 'description', 'TEXTURE', 70), ('テクスチャ変更', 'Texture Change', 'description', 'TEXTURE', 71), ('テクスチャ乗算', 'Texture Multiplication', 'description', 'FORCE_TEXTURE', 72), ('テクスチャ合成', 'Texture Composition', 'description', 'NODE_TEXTURE', 73), ('テクスチャセット合成', 'Texture Set Composition', 'description', 'NODE_TEXTURE', 74), ('マテリアル変更', 'Material Change', 'description', 'MATERIAL', 80), ('useredit', 'Material Properties', 'description', 'MATERIAL', 81), ('shader', 'Shader', 'description', 'SHADING_RENDERED', 90), ('', 'Maid Control', ''), ('prop', 'Property', 'description', 'PROPERTIES', 100), ('アタッチポイントの設定', 'Attach Point', 'description', 'HOOK', 110), ('blendset', 'Face Blend-Set', 'description', 'SHAPEKEY_DATA', 120), ('paramset', 'Face Parameter-Set', 'description', 'OPTIONS', 121), ('commenttype', 'Profile Comment Type', 'description', 'TEXT', 130), ('bonemorph', 'Bone Morph', 'description', 'CONSTRAINT_BONE', 140), ('length', 'Hair Length', 'description', 'CONSTRAINT_BONE', 141), ('anime', 'Animation', 'description', 'ANIM', 150), ('animematerial', 'Animation (Material)', 'description', 'ANIM', 151), ('param2', 'Parameter 2', 'description', 'CON_TRANSFORM', 160), ('', 'Misc.', ''), ('setstr', 'Set String', 'Unused', 'BLANK1', 170), ('onclickmenu', 'onclickmenu', 'Decorative', 'NONE', 200), ('属性追加', 'addattribute', 'Decorative', 'NONE', 201), ('NONE', 'Custom', 'Some other manually entered miscillaneous command', 'GREASEPENCIL', -1)]
type: <_PropertyDeferred, <built-in function EnumProperty>, {'items': [('', 'Menu Meta', ''), ('end', 'End', 'description', 'X', 0), ('name', 'Menu Name', 'description', 'FILE_TEXT', 3), ('saveitem', 'Menu Category', 'description', 'FILE_TEXT', 4), ('setumei', 'Menu Description', 'description', 'FILE_TEXT', 5), ('priority', 'Priority', 'description', 'SORT_DESC', 6), ('メニューフォルダ', 'Folder', 'description', 'FILE_FOLDER', 7), ('icon', 'Icon', 'description', 'FILE_IMAGE', 10), ('icons', 'Icon (Small)', 'description', 'FILE_IMAGE', 11), ('iconl', 'Icon (Large)', 'Unused', 'BLANK1', 12), ('', 'Item Meta', ''), ('ver', 'Item Version', 'description', 'FILE_TEXT', 20), ('category', 'Item Category', 'description', 'SORTALPHA', 21), ('catno', 'Item Category Number', 'description', 'LINENUMBERS_ON', 22), ('アイテム', 'Item', 'description', 'FILE_3D', 30), ('アイテム条件', 'Item Conditions', 'description', 'SCRIPTPLUGINS', 31), ('if', 'Item If', 'description', 'FILE_SCRIPT', 32), ('アイテムパラメータ', 'Item Parameters', 'description', 'SCRIPTPLUGINS', 33), ('半脱ぎ', 'Item Half Off', 'description', 'LIBRARY_DATA_INDIRECT', 34), ('リソース参照', 'Item Resource Reference', 'description', 'LIBRARY_DATA_INDIRECT', 35), ('', 'Item Control', ''), ('set', 'Set', 'Unused', 'BLANK1', 40), ('setname', 'Set Name', 'Unused', 'BLANK1', 41), ('setslotitem', 'Set Slot Item', 'description', 'FILE_TICK', 42), ('additem', 'Add Item', 'description', 'ADD', 43), ('unsetitem', 'Unset Item', 'description', 'REMOVE', 44), ('nofloory', 'Disable Item Floor', 'description', 'CON_FLOOR', 45), ('maskitem', 'Mask Item', 'description', 'MOD_MASK', 46), ('delitem', 'Delete Item', 'description', 'TRASH', 47), ('node消去', 'Node Hide', 'description', 'HIDE_ON', 50), ('node表示', 'Node Display', 'description', 'HIDE_OFF', 51), ('パーツnode消去', 'Parts-Node Hide', 'description', 'VIS_SEL_01', 52), ('パーツnode表示', 'Parts-Node Display', 'description', 'VIS_SEL_11', 53), ('', 'Material Control', ''), ('color', 'Color', 'description', 'COLOR', 60), ('mancolor', 'Man Color', 'description', 'GHOST_ENABLED', 61), ('color_set', 'Color-Set', 'description', 'GROUP_VCOL', 62), ('tex', 'Texture', 'description', 'TEXTURE', 70), ('テクスチャ変更', 'Texture Change', 'description', 'TEXTURE', 71), ('テクスチャ乗算', 'Texture Multiplication', 'description', 'FORCE_TEXTURE', 72), ('テクスチャ合成', 'Texture Composition', 'description', 'NODE_TEXTURE', 73), ('テクスチャセット合成', 'Texture Set Composition', 'description', 'NODE_TEXTURE', 74), ('マテリアル変更', 'Material Change', 'description', 'MATERIAL', 80), ('useredit', 'Material Properties', 'description', 'MATERIAL', 81), ('shader', 'Shader', 'description', 'SHADING_RENDERED', 90), ('', 'Maid Control', ''), ('prop', 'Property', 'description', 'PROPERTIES', 100), ('アタッチポイントの設定', 'Attach Point', 'description', 'HOOK', 110), ('blendset', 'Face Blend-Set', 'description', 'SHAPEKEY_DATA', 120), ('paramset', 'Face Parameter-Set', 'description', 'OPTIONS', 121), ('commenttype', 'Profile Comment Type', 'description', 'TEXT', 130), ('bonemorph', 'Bone Morph', 'description', 'CONSTRAINT_BONE', 140), ('length', 'Hair Length', 'description', 'CONSTRAINT_BONE', 141), ('anime', 'Animation', 'description', 'ANIM', 150), ('animematerial', 'Animation (Material)', 'description', 'ANIM', 151), ('param2', 'Parameter 2', 'description', 'CON_TRANSFORM', 160), ('', 'Misc.', ''), ('setstr', 'Set String', 'Unused', 'BLANK1', 170), ('onclickmenu', 'onclickmenu', 'Decorative', 'NONE', 200), ('属性追加', 'addattribute', 'Decorative', 'NONE', 201), ('NONE', 'Custom', 'Some other manually entered miscillaneous command', 'GREASEPENCIL', -1)], 'name': 'Type', 'default': 'NONE', 'attr': 'type'}> =
<_PropertyDeferred, <built-in function EnumProperty>, {'items': [('', 'Menu Meta', ''), ('end', 'End', 'description', 'X', 0), ('name', 'Menu Name', 'description', 'FILE_TEXT', 3), ('saveitem', 'Menu Category', 'description', 'FILE_TEXT', 4), ('setumei', 'Menu Description', 'description', 'FILE_TEXT', 5), ('priority', 'Priority', 'description', 'SORT_DESC', 6), ('メニューフォルダ', 'Folder', 'description', 'FILE_FOLDER', 7), ('icon', 'Icon', 'description', 'FILE_IMAGE', 10), ('icons', 'Icon (Small)', 'description', 'FILE_IMAGE', 11), ('iconl', 'Icon (Large)', 'Unused', 'BLANK1', 12), ('', 'Item Meta', ''), ('ver', 'Item Version', 'description', 'FILE_TEXT', 20), ('category', 'Item Category', 'description', 'SORTALPHA', 21), ('catno', 'Item Category Number', 'description', 'LINENUMBERS_ON', 22), ('アイテム', 'Item', 'description', 'FILE_3D', 30), ('アイテム条件', 'Item Conditions', 'description', 'SCRIPTPLUGINS', 31), ('if', 'Item If', 'description', 'FILE_SCRIPT', 32), ('アイテムパラメータ', 'Item Parameters', 'description', 'SCRIPTPLUGINS', 33), ('半脱ぎ', 'Item Half Off', 'description', 'LIBRARY_DATA_INDIRECT', 34), ('リソース参照', 'Item Resource Reference', 'description', 'LIBRARY_DATA_INDIRECT', 35), ('', 'Item Control', ''), ('set', 'Set', 'Unused', 'BLANK1', 40), ('setname', 'Set Name', 'Unused', 'BLANK1', 41), ('setslotitem', 'Set Slot Item', 'description', 'FILE_TICK', 42), ('additem', 'Add Item', 'description', 'ADD', 43), ('unsetitem', 'Unset Item', 'description', 'REMOVE', 44), ('nofloory', 'Disable Item Floor', 'description', 'CON_FLOOR', 45), ('maskitem', 'Mask Item', 'description', 'MOD_MASK', 46), ('delitem', 'Delete Item', 'description', 'TRASH', 47), ('node消去', 'Node Hide', 'description', 'HIDE_ON', 50), ('node表示', 'Node Display', 'description', 'HIDE_OFF', 51), ('パーツnode消去', 'Parts-Node Hide', 'description', 'VIS_SEL_01', 52), ('パーツnode表示', 'Parts-Node Display', 'description', 'VIS_SEL_11', 53), ('', 'Material Control', ''), ('color', 'Color', 'description', 'COLOR', 60), ('mancolor', 'Man Color', 'description', 'GHOST_ENABLED', 61), ('color_set', 'Color-Set', 'description', 'GROUP_VCOL', 62), ('tex', 'Texture', 'description', 'TEXTURE', 70), ('テクスチャ変更', 'Texture Change', 'description', 'TEXTURE', 71), ('テクスチャ乗算', 'Texture Multiplication', 'description', 'FORCE_TEXTURE', 72), ('テクスチャ合成', 'Texture Composition', 'description', 'NODE_TEXTURE', 73), ('テクスチャセット合成', 'Texture Set Composition', 'description', 'NODE_TEXTURE', 74), ('マテリアル変更', 'Material Change', 'description', 'MATERIAL', 80), ('useredit', 'Material Properties', 'description', 'MATERIAL', 81), ('shader', 'Shader', 'description', 'SHADING_RENDERED', 90), ('', 'Maid Control', ''), ('prop', 'Property', 'description', 'PROPERTIES', 100), ('アタッチポイントの設定', 'Attach Point', 'description', 'HOOK', 110), ('blendset', 'Face Blend-Set', 'description', 'SHAPEKEY_DATA', 120), ('paramset', 'Face Parameter-Set', 'description', 'OPTIONS', 121), ('commenttype', 'Profile Comment Type', 'description', 'TEXT', 130), ('bonemorph', 'Bone Morph', 'description', 'CONSTRAINT_BONE', 140), ('length', 'Hair Length', 'description', 'CONSTRAINT_BONE', 141), ('anime', 'Animation', 'description', 'ANIM', 150), ('animematerial', 'Animation (Material)', 'description', 'ANIM', 151), ('param2', 'Parameter 2', 'description', 'CON_TRANSFORM', 160), ('', 'Misc.', ''), ('setstr', 'Set String', 'Unused', 'BLANK1', 170), ('onclickmenu', 'onclickmenu', 'Decorative', 'NONE', 200), ('属性追加', 'addattribute', 'Decorative', 'NONE', 201), ('NONE', 'Custom', 'Some other manually entered miscillaneous command', 'GREASEPENCIL', -1)], 'name': 'Type', 'default': 'NONE', 'attr': 'type'}>
string: <_PropertyDeferred, <built-in function StringProperty>, {'name': 'String', 'default': 'newcommand', 'attr': 'string'}> =
<_PropertyDeferred, <built-in function StringProperty>, {'name': 'String', 'default': 'newcommand', 'attr': 'string'}>
Inherited Members
- bpy_types.Operator
- as_keywords
- poll_message_set
- builtins.bpy_struct
- keys
- values
- items
- get
- pop
- as_pointer
- keyframe_insert
- keyframe_delete
- driver_add
- driver_remove
- is_property_set
- property_unset
- is_property_readonly
- is_property_overridable_library
- property_overridable_library_set
- path_resolve
- path_from_id
- type_recast
- bl_rna_get_subclass_py
- bl_rna_get_subclass
- id_properties_ensure
- id_properties_clear
- id_properties_ui
- id_data
@compat.BlRegister()
class
CM3D2MENU_OT_command_remove236@compat.BlRegister() 237class CM3D2MENU_OT_command_remove(bpy.types.Operator): 238 bl_idname = 'cm3d2menu.command_remove' 239 bl_label = "Remove Command" 240 bl_description = "Removes the active CM3D2MenuCommand from the active CM3D2Menu" 241 bl_options = {'REGISTER', 'UNDO'} 242 243 @classmethod 244 def poll(cls, context): 245 ob = context.object 246 if ob and len(ob.cm3d2_menu.commands) - ob.cm3d2_menu.active_index > 0: 247 return True 248 return False 249 250 def execute(self, context): 251 ob = context.object 252 cm3d2_menu = ob.cm3d2_menu 253 cm3d2_menu.remove_command(cm3d2_menu.active_index) 254 if cm3d2_menu.active_index >= len(cm3d2_menu.commands): 255 cm3d2_menu.active_index = len(cm3d2_menu.commands) - 1 256 257 return {'FINISHED'}
Inherited Members
- bpy_types.Operator
- as_keywords
- poll_message_set
- builtins.bpy_struct
- keys
- values
- items
- get
- pop
- as_pointer
- keyframe_insert
- keyframe_delete
- driver_add
- driver_remove
- is_property_set
- property_unset
- is_property_readonly
- is_property_overridable_library
- property_overridable_library_set
- path_resolve
- path_from_id
- type_recast
- bl_rna_get_subclass_py
- bl_rna_get_subclass
- id_properties_ensure
- id_properties_clear
- id_properties_ui
- id_data
@compat.BlRegister()
class
CM3D2MENU_OT_command_move260@compat.BlRegister() 261class CM3D2MENU_OT_command_move(bpy.types.Operator): 262 bl_idname = 'cm3d2menu.command_move' 263 bl_label = "Move Command" 264 bl_description = "Moves the active CM3D2MenuCommand up/down in the list" 265 bl_options = {'REGISTER', 'UNDO'} 266 267 items = [ 268 ('UP' , "Up" , "Move the active CM3D2MenuCommand up in the list" ), 269 ('DOWN', "Down", "Move the active CM3D2MenuCommand down in the list"), 270 ] 271 direction = bpy.props.EnumProperty(items=items, name="Direction") 272 273 @classmethod 274 def poll(cls, context): 275 ob = context.object 276 if ob and len(ob.cm3d2_menu.commands) - ob.cm3d2_menu.active_index > 0: 277 return True 278 return False 279 280 def execute(self, context): 281 ob = context.object 282 cm3d2_menu = ob.cm3d2_menu 283 284 new_index = cm3d2_menu.active_index - 1 if self.direction == 'UP' else cm3d2_menu.active_index + 1 285 if new_index >= len(cm3d2_menu.commands): 286 new_index = len(cm3d2_menu.commands) - 1 287 elif new_index < 0: 288 new_index = 0 289 290 cm3d2_menu.move_command(cm3d2_menu.active_index, new_index) 291 cm3d2_menu.active_index = new_index 292 293 return {'FINISHED'}
items =
[('UP', 'Up', 'Move the active CM3D2MenuCommand up in the list'), ('DOWN', 'Down', 'Move the active CM3D2MenuCommand down in the list')]
direction: <_PropertyDeferred, <built-in function EnumProperty>, {'items': [('UP', 'Up', 'Move the active CM3D2MenuCommand up in the list'), ('DOWN', 'Down', 'Move the active CM3D2MenuCommand down in the list')], 'name': 'Direction', 'attr': 'direction'}> =
<_PropertyDeferred, <built-in function EnumProperty>, {'items': [('UP', 'Up', 'Move the active CM3D2MenuCommand up in the list'), ('DOWN', 'Down', 'Move the active CM3D2MenuCommand down in the list')], 'name': 'Direction', 'attr': 'direction'}>
def
execute(self, context):
280 def execute(self, context): 281 ob = context.object 282 cm3d2_menu = ob.cm3d2_menu 283 284 new_index = cm3d2_menu.active_index - 1 if self.direction == 'UP' else cm3d2_menu.active_index + 1 285 if new_index >= len(cm3d2_menu.commands): 286 new_index = len(cm3d2_menu.commands) - 1 287 elif new_index < 0: 288 new_index = 0 289 290 cm3d2_menu.move_command(cm3d2_menu.active_index, new_index) 291 cm3d2_menu.active_index = new_index 292 293 return {'FINISHED'}
Inherited Members
- bpy_types.Operator
- as_keywords
- poll_message_set
- builtins.bpy_struct
- keys
- values
- get
- pop
- as_pointer
- keyframe_insert
- keyframe_delete
- driver_add
- driver_remove
- is_property_set
- property_unset
- is_property_readonly
- is_property_overridable_library
- property_overridable_library_set
- path_resolve
- path_from_id
- type_recast
- bl_rna_get_subclass_py
- bl_rna_get_subclass
- id_properties_ensure
- id_properties_clear
- id_properties_ui
- id_data
@compat.BlRegister()
class
CM3D2MENU_OT_align_selected_to_attach_point302@compat.BlRegister() 303class CM3D2MENU_OT_align_selected_to_attach_point(bpy.types.Operator): 304 bl_idname = 'cm3d2menu.align_selected_to_attach_point' 305 bl_label = "Align Selected to Attach Point" 306 bl_description = "Align other selected objects to the active object's active CM3D2 attach point" 307 bl_options = {'REGISTER', 'UNDO'} 308 309 scale = bpy.props.FloatProperty(name="Scale", default=5, min=0.1, max=100, soft_min=0.1, soft_max=100, step=100, precision=1, description="The amount by which the mesh is scaled when imported. Recommended that you use the same when at the time of export.") 310 311 @classmethod 312 def poll(cls, context): 313 ob = context.object 314 arm_ob = None 315 if ob.type == 'ARMATURE': 316 arm_ob = ob 317 else: 318 arm_ob = ob.find_armature() 319 if (not arm_ob) and (ob.parent and ob.parent.type == 'ARMATURE'): 320 arm_ob = ob.parent 321 322 if arm_ob and arm_ob.type == 'ARMATURE': 323 active_command = ob.cm3d2_menu.get_active_command() 324 if type(active_command) != menu_file.CM3D2MENU_PG_AttachPointCommand: 325 return False 326 327 selection = None 328 try: 329 selection = context.selected_editable_objects 330 except: 331 return False 332 333 if not selection or len(selection) < 1: 334 return False 335 336 for selected in selection: 337 if selected != arm_ob and selected != ob: 338 return True 339 340 return False 341 342 def invoke(self, context, event): 343 self.scale = common.preferences().scale 344 return context.window_manager.invoke_props_dialog(self) 345 346 def draw(self, context): 347 self.layout.prop(self, 'scale') 348 349 def execute(self, context): 350 ob = context.object 351 if ob.type == 'ARMATURE': 352 arm_ob = ob 353 else: 354 arm_ob = ob.find_armature() 355 if (not arm_ob) and (ob.parent and ob.parent.type == 'ARMATURE'): 356 arm_ob = ob.parent 357 selection = context.selected_editable_objects 358 359 attach_point = ob.cm3d2_menu.get_active_command() 360 attach_mat = attach_point.rotation.to_matrix().to_4x4() 361 attach_mat.translation = attach_point.location.copy() * self.scale 362 363 attach_basis = compat.convert_cm_to_bl_space(attach_mat) 364 attach_basis = compat.convert_cm_to_bl_bone_rotation(attach_basis) 365 366 for selected in selection: 367 if selected == arm_ob or selected == ob: 368 continue 369 const = selected.constraints.get("CM3D2 Attachment") 370 if not const: 371 const = selected.constraints.new("CHILD_OF") 372 const.name = "CM3D2 Attachment" 373 const.target = arm_ob 374 selected.matrix_basis = attach_basis 375 376 return {'FINISHED'}
scale: <_PropertyDeferred, <built-in function FloatProperty>, {'name': 'Scale', 'default': 5, 'min': 0.1, 'max': 100, 'soft_min': 0.1, 'soft_max': 100, 'step': 100, 'precision': 1, 'description': 'The amount by which the mesh is scaled when imported. Recommended that you use the same when at the time of export.', 'attr': 'scale'}> =
<_PropertyDeferred, <built-in function FloatProperty>, {'name': 'Scale', 'default': 5, 'min': 0.1, 'max': 100, 'soft_min': 0.1, 'soft_max': 100, 'step': 100, 'precision': 1, 'description': 'The amount by which the mesh is scaled when imported. Recommended that you use the same when at the time of export.', 'attr': 'scale'}>
@classmethod
def
poll(cls, context):
311 @classmethod 312 def poll(cls, context): 313 ob = context.object 314 arm_ob = None 315 if ob.type == 'ARMATURE': 316 arm_ob = ob 317 else: 318 arm_ob = ob.find_armature() 319 if (not arm_ob) and (ob.parent and ob.parent.type == 'ARMATURE'): 320 arm_ob = ob.parent 321 322 if arm_ob and arm_ob.type == 'ARMATURE': 323 active_command = ob.cm3d2_menu.get_active_command() 324 if type(active_command) != menu_file.CM3D2MENU_PG_AttachPointCommand: 325 return False 326 327 selection = None 328 try: 329 selection = context.selected_editable_objects 330 except: 331 return False 332 333 if not selection or len(selection) < 1: 334 return False 335 336 for selected in selection: 337 if selected != arm_ob and selected != ob: 338 return True 339 340 return False
def
execute(self, context):
349 def execute(self, context): 350 ob = context.object 351 if ob.type == 'ARMATURE': 352 arm_ob = ob 353 else: 354 arm_ob = ob.find_armature() 355 if (not arm_ob) and (ob.parent and ob.parent.type == 'ARMATURE'): 356 arm_ob = ob.parent 357 selection = context.selected_editable_objects 358 359 attach_point = ob.cm3d2_menu.get_active_command() 360 attach_mat = attach_point.rotation.to_matrix().to_4x4() 361 attach_mat.translation = attach_point.location.copy() * self.scale 362 363 attach_basis = compat.convert_cm_to_bl_space(attach_mat) 364 attach_basis = compat.convert_cm_to_bl_bone_rotation(attach_basis) 365 366 for selected in selection: 367 if selected == arm_ob or selected == ob: 368 continue 369 const = selected.constraints.get("CM3D2 Attachment") 370 if not const: 371 const = selected.constraints.new("CHILD_OF") 372 const.name = "CM3D2 Attachment" 373 const.target = arm_ob 374 selected.matrix_basis = attach_basis 375 376 return {'FINISHED'}
Inherited Members
- bpy_types.Operator
- as_keywords
- poll_message_set
- builtins.bpy_struct
- keys
- values
- items
- get
- pop
- as_pointer
- keyframe_insert
- keyframe_delete
- driver_add
- driver_remove
- is_property_set
- property_unset
- is_property_readonly
- is_property_overridable_library
- property_overridable_library_set
- path_resolve
- path_from_id
- type_recast
- bl_rna_get_subclass_py
- bl_rna_get_subclass
- id_properties_ensure
- id_properties_clear
- id_properties_ui
- id_data
@compat.BlRegister()
class
CM3D2MENU_OT_align_attach_point_to_selected379@compat.BlRegister() 380class CM3D2MENU_OT_align_attach_point_to_selected(bpy.types.Operator): 381 bl_idname = 'cm3d2menu.align_attach_point_to_selected' 382 bl_label = "Align Attach Point to Selected" 383 bl_description = "Align the active CM3D2Menu's active attach point to the first other selected object" 384 bl_options = {'REGISTER', 'UNDO'} 385 386 scale = bpy.props.FloatProperty(name="Scale", default=5, min=0.1, max=100, soft_min=0.1, soft_max=100, step=100, precision=1, description="The amount by which the mesh is scaled when imported. Recommended that you use the same when at the time of export.") 387 388 @classmethod 389 def poll(cls, context): 390 ob = context.object 391 arm_ob = None 392 if ob.type == 'ARMATURE': 393 arm_ob = ob 394 else: 395 arm_ob = ob.find_armature() 396 if (not arm_ob) and (ob.parent and ob.parent.type == 'ARMATURE'): 397 arm_ob = ob.parent 398 399 if arm_ob and arm_ob.type == 'ARMATURE': 400 active_command = ob.cm3d2_menu.get_active_command() 401 if type(active_command) != menu_file.CM3D2MENU_PG_AttachPointCommand: 402 return False 403 404 selection = None 405 try: 406 selection = context.selected_objects 407 except: 408 return False 409 410 if not selection or len(selection) < 1: 411 return False 412 413 for selected in selection: 414 if selected != arm_ob and selected != ob: 415 return True 416 417 return False 418 419 def invoke(self, context, event): 420 self.scale = common.preferences().scale 421 return context.window_manager.invoke_props_dialog(self) 422 423 def draw(self, context): 424 self.layout.prop(self, 'scale') 425 426 def execute(self, context): 427 ob = context.object 428 if ob.type == 'ARMATURE': 429 arm_ob = ob 430 else: 431 arm_ob = ob.find_armature() 432 if (not arm_ob) and (ob.parent and ob.parent.type == 'ARMATURE'): 433 arm_ob = ob.parent 434 selection = context.selected_objects 435 436 attach_point = ob.cm3d2_menu.get_active_command() 437 438 439 for selected in selection: 440 if selected == arm_ob or selected == ob: 441 continue 442 mat = compat.mul(arm_ob.matrix_world.inverted(), selected.matrix_world) 443 mat = compat.convert_bl_to_cm_space(mat) 444 mat = compat.convert_bl_to_cm_bone_rotation(mat) 445 446 attach_point.location = mat.translation * (1/self.scale) 447 attach_point.rotation = mat.to_euler() 448 449 return {'FINISHED'}
bl_description =
"Align the active CM3D2Menu's active attach point to the first other selected object"
scale: <_PropertyDeferred, <built-in function FloatProperty>, {'name': 'Scale', 'default': 5, 'min': 0.1, 'max': 100, 'soft_min': 0.1, 'soft_max': 100, 'step': 100, 'precision': 1, 'description': 'The amount by which the mesh is scaled when imported. Recommended that you use the same when at the time of export.', 'attr': 'scale'}> =
<_PropertyDeferred, <built-in function FloatProperty>, {'name': 'Scale', 'default': 5, 'min': 0.1, 'max': 100, 'soft_min': 0.1, 'soft_max': 100, 'step': 100, 'precision': 1, 'description': 'The amount by which the mesh is scaled when imported. Recommended that you use the same when at the time of export.', 'attr': 'scale'}>
@classmethod
def
poll(cls, context):
388 @classmethod 389 def poll(cls, context): 390 ob = context.object 391 arm_ob = None 392 if ob.type == 'ARMATURE': 393 arm_ob = ob 394 else: 395 arm_ob = ob.find_armature() 396 if (not arm_ob) and (ob.parent and ob.parent.type == 'ARMATURE'): 397 arm_ob = ob.parent 398 399 if arm_ob and arm_ob.type == 'ARMATURE': 400 active_command = ob.cm3d2_menu.get_active_command() 401 if type(active_command) != menu_file.CM3D2MENU_PG_AttachPointCommand: 402 return False 403 404 selection = None 405 try: 406 selection = context.selected_objects 407 except: 408 return False 409 410 if not selection or len(selection) < 1: 411 return False 412 413 for selected in selection: 414 if selected != arm_ob and selected != ob: 415 return True 416 417 return False
def
execute(self, context):
426 def execute(self, context): 427 ob = context.object 428 if ob.type == 'ARMATURE': 429 arm_ob = ob 430 else: 431 arm_ob = ob.find_armature() 432 if (not arm_ob) and (ob.parent and ob.parent.type == 'ARMATURE'): 433 arm_ob = ob.parent 434 selection = context.selected_objects 435 436 attach_point = ob.cm3d2_menu.get_active_command() 437 438 439 for selected in selection: 440 if selected == arm_ob or selected == ob: 441 continue 442 mat = compat.mul(arm_ob.matrix_world.inverted(), selected.matrix_world) 443 mat = compat.convert_bl_to_cm_space(mat) 444 mat = compat.convert_bl_to_cm_bone_rotation(mat) 445 446 attach_point.location = mat.translation * (1/self.scale) 447 attach_point.rotation = mat.to_euler() 448 449 return {'FINISHED'}
Inherited Members
- bpy_types.Operator
- as_keywords
- poll_message_set
- builtins.bpy_struct
- keys
- values
- items
- get
- pop
- as_pointer
- keyframe_insert
- keyframe_delete
- driver_add
- driver_remove
- is_property_set
- property_unset
- is_property_readonly
- is_property_overridable_library
- property_overridable_library_set
- path_resolve
- path_from_id
- type_recast
- bl_rna_get_subclass_py
- bl_rna_get_subclass
- id_properties_ensure
- id_properties_clear
- id_properties_ui
- id_data
@compat.BlRegister()
class
CM3D2MENU_OT_param_add455@compat.BlRegister() 456class CM3D2MENU_OT_param_add(bpy.types.Operator): 457 bl_idname = 'cm3d2menu.param_add' 458 bl_label = "Add Parameter" 459 bl_description = "Adds a new CM3D2MenuParam to the active CM3D2MenuCommand" 460 bl_options = {'REGISTER', 'UNDO'} 461 462 @classmethod 463 def poll(cls, context): 464 ob = context.object 465 if ob and ob.cm3d2_menu: 466 misc_command = ob.cm3d2_menu.get_active_command() 467 if type(misc_command) == menu_file.CM3D2MENU_PG_MiscCommand: 468 return True 469 return False 470 471 def execute(self, context): 472 ob = context.object 473 cm3d2_menu = ob.cm3d2_menu 474 misc_command = ob.cm3d2_menu.get_active_command() 475 misc_command.new_param() 476 misc_command.active_index = len(misc_command.params) - 1 477 478 return {'FINISHED'}
Inherited Members
- bpy_types.Operator
- as_keywords
- poll_message_set
- builtins.bpy_struct
- keys
- values
- items
- get
- pop
- as_pointer
- keyframe_insert
- keyframe_delete
- driver_add
- driver_remove
- is_property_set
- property_unset
- is_property_readonly
- is_property_overridable_library
- property_overridable_library_set
- path_resolve
- path_from_id
- type_recast
- bl_rna_get_subclass_py
- bl_rna_get_subclass
- id_properties_ensure
- id_properties_clear
- id_properties_ui
- id_data
@compat.BlRegister()
class
CM3D2MENU_OT_param_remove481@compat.BlRegister() 482class CM3D2MENU_OT_param_remove(bpy.types.Operator): 483 bl_idname = 'cm3d2menu.param_remove' 484 bl_label = "Remove Parameter" 485 bl_description = "Removes the active CM3D2MenuParam from the active CM3D2MenuCommand" 486 bl_options = {'REGISTER', 'UNDO'} 487 488 @classmethod 489 def poll(cls, context): 490 ob = context.object 491 if not ob or not ob.cm3d2_menu: 492 return False 493 494 misc_command = ob.cm3d2_menu.get_active_command() 495 if type(misc_command) != menu_file.CM3D2MENU_PG_MiscCommand: 496 return False 497 498 if len(misc_command.params) - misc_command.active_index <= 0: 499 return False 500 501 return True 502 503 def execute(self, context): 504 ob = context.object 505 cm3d2_menu = ob.cm3d2_menu 506 misc_command = ob.cm3d2_menu.get_active_command() 507 misc_command.remove_param(misc_command.active_index) 508 if misc_command.active_index >= len(misc_command.params): 509 misc_command.active_index = len(misc_command.params) - 1 510 511 return {'FINISHED'}
@classmethod
def
poll(cls, context):
488 @classmethod 489 def poll(cls, context): 490 ob = context.object 491 if not ob or not ob.cm3d2_menu: 492 return False 493 494 misc_command = ob.cm3d2_menu.get_active_command() 495 if type(misc_command) != menu_file.CM3D2MENU_PG_MiscCommand: 496 return False 497 498 if len(misc_command.params) - misc_command.active_index <= 0: 499 return False 500 501 return True
def
execute(self, context):
503 def execute(self, context): 504 ob = context.object 505 cm3d2_menu = ob.cm3d2_menu 506 misc_command = ob.cm3d2_menu.get_active_command() 507 misc_command.remove_param(misc_command.active_index) 508 if misc_command.active_index >= len(misc_command.params): 509 misc_command.active_index = len(misc_command.params) - 1 510 511 return {'FINISHED'}
Inherited Members
- bpy_types.Operator
- as_keywords
- poll_message_set
- builtins.bpy_struct
- keys
- values
- items
- get
- pop
- as_pointer
- keyframe_insert
- keyframe_delete
- driver_add
- driver_remove
- is_property_set
- property_unset
- is_property_readonly
- is_property_overridable_library
- property_overridable_library_set
- path_resolve
- path_from_id
- type_recast
- bl_rna_get_subclass_py
- bl_rna_get_subclass
- id_properties_ensure
- id_properties_clear
- id_properties_ui
- id_data
@compat.BlRegister()
class
CM3D2MENU_OT_param_move514@compat.BlRegister() 515class CM3D2MENU_OT_param_move(bpy.types.Operator): 516 bl_idname = 'cm3d2menu.param_move' 517 bl_label = "Move Parameter" 518 bl_description = "Moves the active CM3D2MenuParameter up/down in the list" 519 bl_options = {'REGISTER', 'UNDO'} 520 521 items = [ 522 ('UP' , "Up" , "Move the active CM3D2MenuCommand up in the list" ), 523 ('DOWN', "Down", "Move the active CM3D2MenuCommand down in the list"), 524 ] 525 direction = bpy.props.EnumProperty(items=items, name="Direction") 526 527 @classmethod 528 def poll(cls, context): 529 ob = context.object 530 if not ob or not ob.cm3d2_menu: 531 return False 532 533 misc_command = ob.cm3d2_menu.get_active_command() 534 if type(misc_command) != menu_file.CM3D2MENU_PG_MiscCommand: 535 return False 536 537 if len(misc_command.params) - misc_command.active_index <= 0: 538 return False 539 540 return True 541 542 def execute(self, context): 543 ob = context.object 544 cm3d2_menu = ob.cm3d2_menu 545 misc_command = ob.cm3d2_menu.get_active_command() 546 547 new_index = misc_command.active_index - 1 if self.direction == 'UP' else misc_command.active_index + 1 548 if new_index >= len(misc_command.params): 549 new_index = len(misc_command.params) - 1 550 elif new_index < 0: 551 new_index = 0 552 553 misc_command.move_param(misc_command.active_index, new_index) 554 misc_command.active_index = new_index 555 556 return {'FINISHED'}
items =
[('UP', 'Up', 'Move the active CM3D2MenuCommand up in the list'), ('DOWN', 'Down', 'Move the active CM3D2MenuCommand down in the list')]
direction: <_PropertyDeferred, <built-in function EnumProperty>, {'items': [('UP', 'Up', 'Move the active CM3D2MenuCommand up in the list'), ('DOWN', 'Down', 'Move the active CM3D2MenuCommand down in the list')], 'name': 'Direction', 'attr': 'direction'}> =
<_PropertyDeferred, <built-in function EnumProperty>, {'items': [('UP', 'Up', 'Move the active CM3D2MenuCommand up in the list'), ('DOWN', 'Down', 'Move the active CM3D2MenuCommand down in the list')], 'name': 'Direction', 'attr': 'direction'}>
@classmethod
def
poll(cls, context):
527 @classmethod 528 def poll(cls, context): 529 ob = context.object 530 if not ob or not ob.cm3d2_menu: 531 return False 532 533 misc_command = ob.cm3d2_menu.get_active_command() 534 if type(misc_command) != menu_file.CM3D2MENU_PG_MiscCommand: 535 return False 536 537 if len(misc_command.params) - misc_command.active_index <= 0: 538 return False 539 540 return True
def
execute(self, context):
542 def execute(self, context): 543 ob = context.object 544 cm3d2_menu = ob.cm3d2_menu 545 misc_command = ob.cm3d2_menu.get_active_command() 546 547 new_index = misc_command.active_index - 1 if self.direction == 'UP' else misc_command.active_index + 1 548 if new_index >= len(misc_command.params): 549 new_index = len(misc_command.params) - 1 550 elif new_index < 0: 551 new_index = 0 552 553 misc_command.move_param(misc_command.active_index, new_index) 554 misc_command.active_index = new_index 555 556 return {'FINISHED'}
Inherited Members
- bpy_types.Operator
- as_keywords
- poll_message_set
- builtins.bpy_struct
- keys
- values
- get
- pop
- as_pointer
- keyframe_insert
- keyframe_delete
- driver_add
- driver_remove
- is_property_set
- property_unset
- is_property_readonly
- is_property_overridable_library
- property_overridable_library_set
- path_resolve
- path_from_id
- type_recast
- bl_rna_get_subclass_py
- bl_rna_get_subclass
- id_properties_ensure
- id_properties_clear
- id_properties_ui
- id_data